#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib
import datetime
import dateutil.parser
import traceback
from gettext import gettext as _

from gnomeagenda.CalendarProviderBase import CalendarProviderBase
from gnomeagenda.appointment import *
#import calendarcontrol.appointment

# use vobject
try:
	import vobject

except:
	print _("Not all dependencies for iCalendar are met.")
	print _("python-vobject (0.5) is required.")
	raise ImportError
	
class iCalCalendar(CalendarProviderBase):
	"""retrieve Events from iCalendars"""
	capabilities = ['provider']
	def __init__(self):
		CalendarProviderBase.__init__(self)
		self.Plugin_Name= "iCalendar"
		self.Plugin_Author = "Florian Dorn"
		
		self.options['urls'] = []
		self.options['colors'] = []
		
	def initPlugin(self,options):
		CalendarProviderBase.initPlugin(self,options)
		pass
		#self.urls = options['urls']
		#self.color = options['colors']
	def getAllEvents(self):
		self.notify_query_provider()
		try:
			tmpfile = urllib.urlretrieve(self.url)[0]
			ical = open(tmpfile,'rb').read()
		except:
			self.notifyError(_("Could not access Calendar"))
			return
		self.getEventsFromString(ical)

	
	def parseEvent(self,ev,url):
		
		skipped_item = False
		summary = ""
		ev_id = ""
		description =""
		start = ""
		end = ""
		status = "CONFIRMED"
		
		#get start and end time
		start 	=  convert_datetime(str(ev.dtstart.value))
		end 	=  convert_datetime(str(ev.dtend.value))
		exdates = []
		duration = end - start
		#end times are computed based on the duration
		start_times = [start]

		try:
			summary =  ev.summary.value.strip()
		except:
			summary = _("No title available")
		try:
			ev_id = ev.uid.value.strip()
		except:
			ev_id = "gnome-agenda-generated-id-%s" % time.time()
		try:
			description = ev.description.value.strip()
		except:
			description = ""
		try:
			place = ev.location.value.strip()
		except Exception, e:
			place = ""
		try:
			status = ev.status.value.strip()
		except Exception, e:
			status ="CONFIRMED"


		try:
			rruleset = ev.rruleset
			if(rruleset):
				"""evo creates until values as Dates. this is wrong. it should be a datetime mathcing the startdate"""
				st = start.time()
				for rrule in rruleset._rrule:
					if( rrule._until):
						rrule._until = rrule._until.replace(hour=st.hour,minute=st.minute, second=st.second)

				now = datetime.datetime.utcnow().replace(hour=0,minute=0,second=0,microsecond=0)

				start_times = rruleset.between(now,now + datetime.timedelta(days=30),True)
				if(len(start_times) == 0):
					return None

		except Exception, e:
			print "Not a valid rruleset"
			print
			print traceback.print_exc()
			ev.prettyPrint()
		"""Evolution creates exdates as datetime.date, vobject requires exdates to exactly match
		the type of the instance (e.g.: datetime/date)"""
		#TODO: what about exrules?
		try:
			if(ev.exdate):
				for ed in ev.exdate_list:
					for value in ed.value:
						if(isinstance(value,datetime.datetime)):
							value = value.date() 
					
						exdates.append(ed.value[0])
				
		except Exception, e:
			#print
			#print traceback.print_exc()
			pass

		try:
			for start in start_times:
				if((start.time() != datetime.time()) or (duration.seconds != 0)):
					start = local2utc(start)
				if (start.date() in exdates):
					continue
				end = start + duration
				#print "  %s  -  %s" % (start,end)
				#print (id, url, start, end,summary,description,place,status)
				self.addEvent(ev_id, url, start, end,summary,description,place,status)
		except Exception, e:
			print traceback.print_exc()
			print e
			print "skipping item: %s" % summary
			if(not skipped_item):
				print description
				self.notifyError(_("Could not parse event [%s]" % (summary)))
				skipped_item = True

	def getEventsFromString(self,string,url):
		if(string == None):
			return
		try:
			c = vobject.readComponents(string).next()
			
			if( c.name == 'VEVENT'):
				self.parseEvent(c,url)
			elif c.name == 'VCALENDAR':
				try:
					c.vevent_list
				except:
					"""has no events"""
					return
				for ev in c.vevent_list:
					self.parseEvent(ev,url)

			else:
				raise "Cannot parse iCal type %s" % (c.name)
		except Exception, e:
			print "ERROR: %s" % e
			print traceback.print_exc()
			self.notifyError(_("Could not parse %s iCalendar Data.\n%s") % (self.Plugin_Name,e))

	def getSettingsPanel(self):
		"""return a gtk Widget showind the settings"""
		return gtk.Label(_("No configuration needed"))
	def applySettings(self):
		"""apply the changes to self.options made to the widgets"""

